package com.osdp.sc.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.osdp.common.util.ConvertUtil;
import com.osdp.sc.entity.ScRolePermission;
import com.osdp.sc.mapper.ScRolePermissionMapper;
import com.osdp.sc.service.IScRolePermissionService;
import com.osdp.sc.uitl.Fields;
import com.osdp.sc.vo.ScRolePermissionVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

@Service
public class ScRolePermissionServiceImpl extends ServiceImpl<ScRolePermissionMapper, ScRolePermission> implements IScRolePermissionService {


    @Override
    @Transactional
    public boolean deleteRolePermByPermId(String id) {
        return this.remove(new QueryWrapper<ScRolePermission>()
                .eq(StringUtils.isNotBlank(id), Fields.ScRolePermissionQ.permissionId,id));

    }
    /**
     * 保存角色权限
     * @param roleId
     * @param permissionIds
     * @param lastPermissionIds
     */
//    @Override
    @Transactional
    public void saveRolePermission(String roleId, String permissionIds, String lastPermissionIds) {
        //从permissionIds 找出 lastPermissionIds 中没有的元素，保存到数据库
        List<String> addPermIdList = getDiff(lastPermissionIds,permissionIds);
        if(!CollectionUtils.isEmpty(addPermIdList)){
            List<ScRolePermission> permList = Lists.newArrayList();
            for(String permId : addPermIdList){
                ScRolePermission entity = new ScRolePermission(roleId,permId);
                permList.add(entity);
            }
            this.saveBatch(permList);
        }
        List<String> deletePermIdList = getDiff(permissionIds,lastPermissionIds);
        if(!CollectionUtils.isEmpty(deletePermIdList)){
            List<ScRolePermission> permList = Lists.newArrayList();
            for(String permId : deletePermIdList){
                this.remove(new QueryWrapper<ScRolePermission>().lambda()
                        .eq(ScRolePermission::getRoleId, roleId)
                        .eq(ScRolePermission::getPermissionId, permId));
            }
        }
    }

    /**
     * 从last中找出front中没有的元素
     * @param front 包含last
     * @param last
     * @return
     */
    private List<String> getDiff(String front, String last){
        if(StringUtils.isEmpty(front)){
            return null;
        }
        if(StringUtils.isEmpty(last)){
            return null;
        }
        String[] fronts = front.split(",");
        String[] lasts = last.split(",");
        Map<String,String> resMap = Maps.newHashMap();
        for(String s : fronts){
            resMap.put(s,s);
        }
        List<String> res = Lists.newArrayList();
        for(String s: lasts){
            if(StringUtils.isEmpty(s) && !resMap.containsKey(s)){
                res.add(s);
            }
        }
        return res;
    }

    @Override
    @Transactional
    public boolean saveRolePermission(String roleId, List<String> permissionIds){
        List<ScRolePermissionVo> existedList = queryRolePermsByRoleId(roleId);
        List<ScRolePermission> addList =  getAddRolePermission(roleId,permissionIds,existedList);
        boolean isSuccess = true;
        if(!CollectionUtils.isEmpty(addList)) {
            isSuccess = super.saveBatch(addList);
        }
        List<String> delIds = getDelRolePermission(roleId, permissionIds, existedList);
        if (!CollectionUtils.isEmpty(delIds)) {
            isSuccess = super.removeByIds(delIds);
        }
        return isSuccess;
    }
    /**
     * 找出新授权的对象
     * @param roleId
     * @param permissionIds
     * @param lastPermissionIds
     * @return
     */
    private List<ScRolePermission> getAddRolePermission(String roleId, List<String> permissionIds, List<ScRolePermissionVo> lastPermissionIds){
        List<ScRolePermission> entityList = new LinkedList<>();
        Map<String,ScRolePermissionVo> voMap = new HashMap<>();
        if(CollectionUtils.isEmpty(lastPermissionIds)){
            lastPermissionIds.stream().forEach(e -> {
                voMap.put(e.getId(),e);
            });
        }
        if(!CollectionUtils.isEmpty(permissionIds)) {
            permissionIds.stream().forEach(id -> {
                if (voMap.get(id) == null) {
                    ScRolePermission entity = new ScRolePermission();
                    entity.setRoleId(roleId);
                    entity.setPermissionId(id);
                    entityList.add(entity);
                }
            });
        }
        return entityList;
    }

    /**
     * 找出需要删除的授权对象
     * @param roleId
     * @param permissionIds
     * @param lastPermissionIds
     * @return
     */
    private List<String> getDelRolePermission(String roleId,  List<String> permissionIds,List<ScRolePermissionVo> lastPermissionIds){
        List<String> idList = new LinkedList<>();
        Map<String,String> idsMap = new HashMap<>();
        if(!CollectionUtils.isEmpty(permissionIds)) {
            permissionIds.stream().forEach(id -> {
                idsMap.put(id, id);
            });
        }
        if(!CollectionUtils.isEmpty(lastPermissionIds)) {
            lastPermissionIds.stream().forEach(vo -> {
                if(idsMap.isEmpty()){
                    idList.add(vo.getId());
                }else {
                    if (idsMap.get(vo.getPermissionId()) == null) {
                        idList.add(vo.getId());
                    }
                }
            });
        }
        return idList;
    }



    @Override
    public List<ScRolePermissionVo> queryRolePermsByRoleId(String roleId){
        List<ScRolePermission> list = super.list(new QueryWrapper<ScRolePermission>()
                .eq(StringUtils.isNotBlank(roleId),Fields.ScRolePermissionQ.roleId, roleId ));
        return ConvertUtil.sourceToTarget(list, ScRolePermissionVo.class);
    }
}
